/* 
 * File:   staticutils.h
 * Author: pable
 *
 * Created on November 26, 2008, 10:15 AM
 */

#ifndef _STATICUTILS_H
#define	_STATICUTILS_H
//#include "EnumArgument.h"
#include <vector>
#include <map>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>

typedef std::vector<std::string> VectorString;

class StaticUtils {
public:
    static VectorString split(std::string,std::string);
    static std::string& trimo(std::string&);
    static std::string trim(std::string);
    static std::string::iterator getAtBuffer(std::string& , int);
    static std::string extractFileName(std::string);
    virtual ~StaticUtils();
    static bool findQuote(std::string &,VectorString&);
    static void printStringFormat(std::string&);
    static bool isNumeric(std::string);
    template <class TIterator>
    static TIterator lowerBound(TIterator begin, std::string& identifier, TIterator end) {
            for ( ; begin != end; begin++) {
                    std::string command = begin->first;
                    int index = command.find(identifier,0);
                    if(index == 0){
                        return begin;
                    }
            }
            return begin;
    }

    template <class TIterator>
    static TIterator upperBound(TIterator it,std::string& identifier, TIterator end) {
            while (it != end) {
                    std::string command = it->first;
                    if ((command.compare(identifier)) != 0) {
                            unsigned int index = command.find(identifier);
                            if (index == 0) {
                                    it++;
                                    continue;
                            } else {
                                    return it;
                            }
                    } else {
                            it++;
                            continue;
                    }
            }
            return it;
    }

    template <class TIterator,class ClassTMap>
    static int findLike(TIterator& itLow, TIterator& itUp, std::string& identifier, ClassTMap& map){
        TIterator ite = map.find(identifier);
        if(ite != map.end()) {
            itLow = ite;
            itUp = ++ite;
        } else {
            itLow = StaticUtils::lowerBound<TIterator>(map.lower_bound(identifier),identifier, map.end());
            itUp = StaticUtils::upperBound<TIterator>(itLow,identifier,map.end());
        }
        return StaticUtils::calculateNodes<TIterator>(itLow,itUp);
    }

     template <class TIterator,class ClassTMap>
    static int findLikeHelp(TIterator& itLow, TIterator& itUp, std::string& identifier, ClassTMap& map){

        itLow = StaticUtils::lowerBound<TIterator>(map.lower_bound(identifier),identifier, map.end());
        itUp = StaticUtils::upperBound<TIterator>(itLow,identifier,map.end());
        return StaticUtils::calculateNodes<TIterator>(itLow,itUp);
    }

    template <class TIterator>
    static int calculateNodes(TIterator first,TIterator second){
        int i=0;
        for(;first != second ; i++,first++ ){
        }
        return i;

    }
    static void clearLine();


    template <class TIterator>
    static std::string* searchForPrefix(TIterator& itLow, TIterator& itUp){
        std::string *returnValue = new std::string("");
        returnValue->push_back(itLow->first[0]);
        int index=0;
        bool stop = false;
        while(!stop){
            index++;
            char c = itLow->first[index];
            for(TIterator it = itLow; it != itUp; it++){
                if(it->first.size() > (index - 1)){
                    if(!(it->first[index] == c)){
                        stop=true;
                        break;
                    }
                } else {
                    stop=true;
                    break;
                }
            }
            if(!stop){
                returnValue->push_back(c);
            }
        }
        return returnValue;
    }

    template <class TIterator>
    static std::string* searchForPrefixVector(TIterator& itLow, TIterator& itUp){
        std::string *returnValue = new std::string("");
        returnValue->push_back((*itLow)[0]);
        int index=0;
        bool stop = false;
        while(!stop){
            index++;
            char c = (*itLow)[index];
            for(TIterator it = itLow; it != itUp; it++){
                if((*it).size() > (index - 1)){
                    if(!((*it)[index] == c)){
                        stop=true;
                        break;
                    }
                } else {
                    stop=true;
                    break;
                }
            }
            if(!stop){
                returnValue->push_back(c);
            }
        }
        return returnValue;
    }

    template <class TIterator>
    static TIterator lowerBoundSet(TIterator begin, std::string& identifier, TIterator end) {
            for ( ; begin != end; begin++) {
                    std::string command = *begin;
                    int index = command.find(identifier,0);
                    if(index == 0){
                        return begin;
                    }
            }
            return begin;
    }

    template <class TIterator>
    static TIterator upperBoundSet(TIterator it,std::string& identifier, TIterator end) {
            while (it != end) {
                    std::string command = *it;
                    if ((command.compare(identifier)) != 0) {
                            unsigned int index = command.find(identifier);
                            if (index == 0) {
                                    it++;
                                    continue;
                            } else {
                                    return it;
                            }
                    } else {
                            it++;
                            continue;
                    }
            }
            return it;
    }

private:
    StaticUtils();
    StaticUtils(const StaticUtils& orig);
};

#endif	/* _STATICUTILS_H */

